package com.ns.sbs.oauth.acc4auth.service;


import com.alibaba.fastjson2.JSON;
import com.ns.core.current.config.SymbolsMark;
import com.ns.core.utils.StpUtil;
import com.ns.core.utils.jwt.SystemUtil;
import com.ns.core.utils.rsa.TokenUtil;
import com.ns.core.utils.sg.IpUtil;
import com.ns.core.utils.sg.NbUtil;
import com.ns.core.utils.sg.ResultError;
import com.ns.core.vo.au.SsoUserVO;
import com.ns.core.vo.login.ServObjVO;
import com.ns.core.vo.login.SucObjVO;
import com.ns.sbs.oauth.acc.mapper.Acc2ServerMapper;
import com.ns.sbs.oauth.acc.mapper.AccountMapper;
import com.ns.sbs.oauth.acc4log.entry.Acc4Log;
import com.ns.sbs.oauth.acc4log.mapper.Acc4LogMapper;
import eu.bitwalker.useragentutils.UserAgent;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;

/**
 * service：admin账号相关
 *
 * @author lw
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AccAuthServiceImpl implements IAccAuthService {

    private final AccountMapper mapper;

    private final Acc4LogMapper sysLoginLogMapper;


    private final Acc2ServerMapper acc2ServerMapper;

    /**
     * 登录
     *
     * @param phone    手机号
     * @param password 密码
     * @return ResultOk
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public SucObjVO doLogin(String phone, String password) {

        // 1、查询账户
        SsoUserVO acc = mapper.getSsoAccByPhone(phone);

        // 2、开始验证
        if (acc == null) {
            throw new ResultError("暂无此账户信息");
        }
        // 3、查询密码
        String pwd = mapper.getAccPwd(acc.getId());
        if (NbUtil.isNull(pwd)) {
            throw new ResultError("此账号尚未设置密码，无法登陆");
        }
        // 4、验证密码
        String inPwd = SystemUtil.getPasswordMd5(acc.getId(), password);
        if (!Objects.equals(pwd, inPwd)) {
            throw new ResultError("密码错误");
        }
        // 5、是否禁用
        if (acc.getStatus() == 0) {
            throw new ResultError("此账号已被禁用，如有疑问，请联系管理员");
        }
        // =========== 已登录成功 ============
        // 生成token
        String token = TokenUtil.generateToken(JSON.toJSONString(acc));
        StpUtil.login(acc.getId(), token);
        this.successLogin(acc, token);
        // 查询账户服务
        List<ServObjVO> svs = acc2ServerMapper.getByAccId(acc.getId());
        if (CollectionUtils.isEmpty(svs)) {
            throw new ResultError("该用户暂无服务可用,请联系管理员!");
        }
        // 组织返回参数
        SucObjVO suc = new SucObjVO();
        suc.setToken(token);
        suc.setU(acc);
        suc.setCurs(svs);
        return suc;
    }

    /**
     * 指定id的账号成功登录一次 （修改最后登录时间等数据 ）
     *
     * @param s     参数
     * @param token token
     */
    @Override
    public void successLogin(SsoUserVO s, String token) {
        HttpServletRequest request = IpUtil.getRequest();
        UserAgent ua = UserAgent.parseUserAgentString(request.getHeader(SymbolsMark.HEADER_USER_AGENT));
        String loginIp = IpUtil.getIP(request);
        // 1、修改 admin表 最后登录日志
        if (mapper.updateLoginLog(s.getId(), loginIp) > 0) {
            // 2、在管理员登录日志表增加记录
            Acc4Log al = new Acc4Log();
            // 管理员id
            al.setAccId(s.getId());
            // 本次登录Token
            al.setAccToken(token);
            // 登陆IP
            al.setLoginIp(loginIp);
            // 客户端所在地址
            al.setAddress(IpUtil.getRequest().getRemoteAddr());
            // 客户端标识
            al.setDevice(ua.getBrowser().getName());
            // 客户端系统
            al.setSystemBy(ua.getOperatingSystem().getName());
            // 租户
            al.setRid(s.getRid());
            sysLoginLogMapper.insertOrUpdate(al);
        }
    }
}
